
/*
 * author: BDG
 * date: Wed 05 Oct 2016 16:58:13 */

#include <cstdio>   // 4 fprintf
#include "face_alignment.h"

FaceAlignment::FaceAlignment(QWidget *parent)
    : QWidget(parent)
{
    cout << "Constructor 0" << endl << endl;

    seetaFA = new SeetaAlignment();
    doAlign = false;    // default do not align

    timer = new QTimer(this);

    setupLayouts();
    //FaceAlignment(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, DEFAULT_TITLE, parent);
}

/*
 * Do not use those two constructors cause unknow reason will let app not work when
 * layout.
 *
FaceAlignment::FaceAlignment(const int width, const int height, QWidget *parent)
{
    cout << "Constructor 1" << endl << endl;
    FaceAlignment(width, height, DEFAULT_TITLE, parent);
}

FaceAlignment::FaceAlignment(const int width, const int height, const string title,QWidget *parent)
    : QWidget(parent)
{
    cout << "Constructor 2" << endl << endl;
    /// Layout
    setupLayouts();

    std::cout << "Init finished." << std::endl;
}
*/

void FaceAlignment::setupLayouts()
{
    label0 = new QLabel("Label 0", this);
    label0->setStyleSheet("background-color:blue;");
    label1 = new QLabel("Label 1", this);
    label1->setStyleSheet("background-color:cyan;");

    QGridLayout *grid = new QGridLayout(this);
    grid->addWidget(label0, 0, 0);
    grid->addWidget(label1, 0, 1);

    setLayout(grid);
}

void FaceAlignment::openCamera()
{
    camera0 = cvCaptureFromCAM(0);
    if (!camera0)
    {
        fprintf(stderr, "Could not initialize Camera 0...\n"); 
        return;
    }
    else
    {
        doCapture = true;
        cout << "Opened camera." << endl;
        timer->start(24);
        connect(timer, SIGNAL(timeout()), this, SLOT(capture()));
        //capture();
    }
    //cout << "Opened camera." << endl;
}

void FaceAlignment::closeCamera()
{
    doCapture = false;
    timer->stop();
    if (camera0 != NULL)
    {
        cvReleaseCapture(&camera0);
    }
    cout << "Closed camera." << endl;
}

void FaceAlignment::capture()
{
    if (doCapture)
    {
        frame = cvQueryFrame(camera0);  // Get a piece of frame

        image = new QImage((const uchar*)frame->imageData,
                    frame->width,
                    frame->height,
                    QImage::Format_RGB888); // Turn this frame to QImage picture
        image = new QImage(image->rgbSwapped());    // RGB transfer
        //label0->setScaledContents(true);    // fit window? not work
        if (doAlign)
        {
            // do alignment
            cout << "Doing align..." << endl;
            string inImagePath = "./tmp_in.jpg";
            cv::Mat mat = cv::cvarrToMat(frame);
            cv::imwrite(inImagePath, mat);
            // next call seeta_alignment
            string outImagePath = "./tmp_out.jpg";
            seetaFA->alignTarget(inImagePath, outImagePath);
            QPixmap pixmap;
            if (pixmap.load(outImagePath.c_str()))
            {
                // Show it
                label0->setPixmap(pixmap);
            }
            else 
            {
                cout << "Error happened when load aligned image." << endl;
            }
        }
        else
        {
            label0->setPixmap(QPixmap::fromImage(*image));   // Show image
        }
    }
}

void FaceAlignment::startAlignment()
{
    cout << "Should start alignment here." << endl;
    // 1. Read image from variable
    // 2. write to a file and save its' path
    // 3. give a new image path then use those two path to call seeta_alignment to work
    // 4. display handled image with its' path
}

void FaceAlignment::stopAlignment()
{
    cout << "Should stop alignment here." << endl;
}

void FaceAlignment::setDoAlign(const bool val)
{
    doAlign = val;
}

